package org.stream.answerduel.controller.api;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.stream.answerduel.controller.BaseController;
import org.stream.answerduel.dto.Result;
import org.stream.answerduel.service.MatchService;
import org.stream.answerduel.vo.AnswerResultVo;
import org.stream.answerduel.vo.MatchingUser;
import org.stream.answerduel.vo.ReconnectVo;
import org.stream.answerduel.vo.Room;
import org.stream.answerduel.vo.WaitingUser;

import java.util.NoSuchElementException;
import java.util.concurrent.ExecutionException;

/**
 * @author 何俊霖
 * @date 2019/7/10 18:00
 *
 *
 */
@Api("匹配和比赛接口")
@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/api/match")
public class MatchController extends BaseController {
    @Autowired
    MatchService matchService;

    /**
     * 功能描述：入参为需要匹配的用户的id， 返回是否成功进入匹配队列
     * 
     * @param id
     * @return Result
     */
    @ApiOperation(value="开始匹配",notes = "开始匹配，返回是否成功进入匹配队列，true表示成功，若为false，则message为进入匹配队列失败的原因")
    @GetMapping("start")
    public ResponseEntity<Result<Boolean>> startMatch(Long id) {
        String message = "正在匹配中";
        Boolean success = true;
        Result<Boolean> result = new Result<Boolean>().ok(message,success);
        try {
            if(matchService.isInQueue(id)){
                success = false;
                message = "用户已经在匹配队列中";
                result = new Result<Boolean>().ok(message,success);
                return new ResponseEntity<Result<Boolean>>( result,HttpStatus.OK);
            }
            if(matchService.isInGame(id)){
                success = false;
                message = "用户已经在游戏中，请尝试重连";
                result = new Result<Boolean>().ok(message,success);
                return new ResponseEntity<Result<Boolean>>( result,HttpStatus.OK);
            }
            matchService.startMatch(id);
        }
        catch (NoSuchElementException e) {
            result = new Result<Boolean>().serverError("用户不存在",false);
            return new ResponseEntity<Result<Boolean>>(result, HttpStatus.INTERNAL_SERVER_ERROR);
        }
        result = new Result<Boolean>().ok(message,success);
        return new ResponseEntity<Result<Boolean>>( result,HttpStatus.OK);
    }

    /**
     * 功能描述：取消用户匹配
     * 
     * @param id 用户id
     * @return Result 结果
     */
    @ApiOperation(value="取消匹配",notes = "取消匹配，返回消息")
    @GetMapping("cancel")
    public ResponseEntity<Result> cancelMatch(Long id){
        boolean isSuccess = matchService.cancelMatch(id);
        if(isSuccess)
            return new ResponseEntity<Result>( new Result().ok("你已取消匹配"),HttpStatus.OK);
        else
            return new ResponseEntity<Result>(new Result().ok("用户不在匹配队列中"), HttpStatus.OK);
    }

    //TODO 增加投降接口

    /**
     * 功能描述：创建房间
     * 
     * @param id 用户id
     * @return Result 结果
     */
    @ApiOperation(value="创建好友房间",notes = "创建好友房间，若创建成功则返回房间号")
    @GetMapping("create")
    public ResponseEntity<Result<String>> createWaitingRoom(Long id){
        String roomID = null;
        String message = "创建房间成功";
        Result<String> result = new Result<String>().ok(message,roomID);
        if(matchService.isInQueue(id)){
            message = "用户已经在匹配队列中";
            result = new Result<Boolean>().ok(message,null);
            return new ResponseEntity<Result<String>>( result,HttpStatus.OK);
        }
        if(matchService.isInGame(id)){
            message = "用户已经在游戏中，请尝试重连";
            result = new Result<Boolean>().ok(message,null);
            return new ResponseEntity<Result<String>>( result,HttpStatus.OK);
        }
        if(matchService.isInAnyWaitingRoom(id)){
            matchService.forceExitWaitingRoom(id);
            log.info("用户："+id+"尝试创建好友房间时，发现该用户已经在某个房间中，现已成功退出原来的房间");
        }
        roomID = matchService.createWaitingRoom(id);
        result = new Result<String>().ok(message,roomID);
        return new ResponseEntity<Result<String>>( result,HttpStatus.OK);
    }

    /**
     * 功能描述：加入房间
     * 
     * @param id 用户id
     * @param roomId 房间号
     * @return Result 结果
     */
    @ApiOperation(value="加入好友房间",notes = "加入好友的游戏房间，返回另一个用户的信息")
    @GetMapping("join")
    public ResponseEntity<Result<WaitingUser>> joinWaitingRoom(Long id, Long friendId, String roomId){
        String message = "该房间可以加入";
        Result<WaitingUser> result = new Result<WaitingUser>().ok(message,null);
        if(friendId.equals(id)){
            message = "不能加入自己创建的房间";
            result = new Result<WaitingUser>().ok(message, null);
            return new ResponseEntity<Result<WaitingUser>>( result,HttpStatus.OK);
        }
        if(matchService.isWaitingRoomExist(roomId) == false) {
            message = "该房间已经不存在了";
            result = new Result<WaitingUser>().ok(message, null);
            return new ResponseEntity<Result<WaitingUser>>( result,HttpStatus.OK);
        }
        if(matchService.isUserInWaitingRoom(friendId,roomId) == false ) {
            message = "邀请你的人已经离开房间";
            result = new Result<WaitingUser>().ok(message, null);
            return new ResponseEntity<Result<WaitingUser>>( result,HttpStatus.OK);
        }
        if(matchService.isWaitingRoomFull(roomId)) {
            message = "该房间已满，无法加入";
            result = new Result<WaitingUser>().ok(message, null);
            return new ResponseEntity<Result<WaitingUser>>( result,HttpStatus.OK);
        }

        WaitingUser waitingUser = matchService.joinWaitingRoom(id,roomId);
        message = "加入好友房间成功";
        result = new Result<WaitingUser>().ok(message,waitingUser);
        
        return new ResponseEntity<Result<WaitingUser>>( result,HttpStatus.OK);
    }

    /**
     * 功能描述：退出房间
     * 
     * @param id 用户id
     * @param roomId 房间号
     * @return Result 结果
     */
    @ApiOperation(value="退出好友房间",notes = "退出好友房间")
    @GetMapping("exit")
    public ResponseEntity<Result> exitWaitingRoom(Long id, String roomId){
        String message = "退出好友房间成功";
        Result<WaitingUser> result = new Result<WaitingUser>().ok(message,null);
        if(matchService.isWaitingRoomExist(roomId) == false) {
            message = "该好友房间已经不存在了";
            result = new Result<WaitingUser>().ok(message, null);
            return new ResponseEntity<Result>( result,HttpStatus.OK);
        }
        matchService.exitWaitingRoom(id,roomId);
        return new ResponseEntity<Result>( new Result().ok(message),HttpStatus.OK);
    }

    /**
     * 功能描述：强制退出房间
     * 
     * @param id 用户id
     * @return Result 结果
     */
    @ApiOperation(value="强制退出好友房间",notes = "强制退出好友房间，在无法开新游戏时使用")
    @GetMapping("foeceExit")
    public ResponseEntity<Result> forceExitWaitingRoom(Long id){
        matchService.forceExitWaitingRoom(id);
        //matchService.forceExitRoom(id);
        return new ResponseEntity<Result>( new Result().ok("强制退出好友房间成功"),HttpStatus.OK);
    }

//    /**
//     * 功能描述：该房间是否存在，且房间里面是邀请者，且房间未满
//     *
//     * @param id 邀请者的用户id
//     * @param roomID 房间号
//     * @return Result 结果
//     */
//    @ApiOperation(value="好友房间是否有效",notes = "判断该好友房间是否存在，且房间里面是邀请者，且房间未满。若返回true，则表示可以加入，返回false表示不能加入，message为不能加入的原因")
//    @GetMapping("isvalid")
//    public ResponseEntity<Result<Boolean>> isValid(Long id, String roomID){
//        Boolean isUserInWaitingRoom = matchService.isUserInWaitingRoom(id,roomID);
//        Boolean isFull = matchService.isWaitingRoomFull(roomID);
//        Boolean isExist = matchService.isWaitingRoomExist(roomID);
//        Result<Boolean> result = new Result<Boolean>().ok("该房间可以加入",true);
//        if(isUserInWaitingRoom == false || isExist == false)
//            result = new Result<Boolean>().ok("邀请你的人已经离开房间",false);
//        if(isFull == true)
//            result = new Result<Boolean>().ok("该房间已满，无法加入",false);
//
//        return new ResponseEntity<Result<Boolean>>(result ,HttpStatus.OK);
//    }


    //@GetMapping("start")
    // public ResponseEntity<Result> startMatch(String wechat_id) {
    //     try {
    //         matchService.startMatch(wechat_id);
    //     } catch (InterruptedException | ExecutionException e) {
    //         e.printStackTrace();
    //         return new ResponseEntity<Result>( new Result().serverError(e),HttpStatus.INTERNAL_SERVER_ERROR);
    //     }
    //     catch (NoSuchElementException e) {
    //         return new ResponseEntity<Result>(new Result().serverError("用户不存在"), HttpStatus.INTERNAL_SERVER_ERROR);
    //     }
    //     return new ResponseEntity<Result>( new Result().ok("正在匹配中"),HttpStatus.OK);
    // }

    @ApiOperation(value = "答题",notes = "回答问题，返回得到的分数,返回null表示输入有误")
    @GetMapping("answer")
    public ResponseEntity<Result<AnswerResultVo>> answer(Long id, Long roomId, int choice)
    {
        if( choice < 1 )
            choice = 1;
        if( choice > 4)
            choice = 4;
        AnswerResultVo answerResult = null;
        try
        {
            answerResult = matchService.answer(id,roomId,choice);
        }
        catch(Exception e)
        {
            e.printStackTrace();
            return new ResponseEntity<Result<AnswerResultVo>>( new Result().serverError(e),HttpStatus.INTERNAL_SERVER_ERROR);
        }
        if(answerResult == null)
            return new ResponseEntity<Result<AnswerResultVo>>( new Result<AnswerResultVo>().result(HttpStatus.OK,"输入有误",answerResult),HttpStatus.OK);
        Result<AnswerResultVo> result = new Result<AnswerResultVo>().ok("答题成功",answerResult);
        return new ResponseEntity<Result<AnswerResultVo>>(result,HttpStatus.OK);
    }

    @ApiOperation(value = "准备",notes = "准备好了之后发送的请求")
    @GetMapping("ready")
    public ResponseEntity<Result<Boolean>> ready(Long id, Long roomId)
    {
        boolean success = true;
        String message = "你已经准备";
        Result<Boolean> result = new Result<Boolean>().ok(message,success);
        if(matchService.isRoomExist(roomId) == false){
            message = "房间不存在";
            success = false;
            result = new Result<Boolean>().result(HttpStatus.OK, message,success);
            return new ResponseEntity<Result<Boolean>>( result,HttpStatus.OK);
        }
        if(matchService.isUserInRoom(id, roomId) == false){
            message = "你不在该房间中";
            success = false;
            result = new Result<Boolean>().result(HttpStatus.OK,message,success);
            return new ResponseEntity<Result<Boolean>>( result,HttpStatus.OK);
        }

        matchService.ready(id, roomId);
        return new ResponseEntity<Result<Boolean>>(result, HttpStatus.OK);
    }

    @ApiOperation(value = "好友房间准备",notes = "好友房间按下准备按钮之后发送的请求")
    @GetMapping("prepare")
    public ResponseEntity<Result<Boolean>> prepare(Long id, String roomId)
    {
        boolean success = true;
        String message = "准备完毕";
        Result<Boolean> result = new Result<Boolean>().ok(message,success);
        if(matchService.isWaitingRoomExist(roomId) == false){
            message = "房间不存在";
            success = false;
            result = new Result<Boolean>().result(HttpStatus.OK, message,success);
            return new ResponseEntity<Result<Boolean>>( result,HttpStatus.OK);
        }
        if(matchService.isUserInWaitingRoom(id, roomId) == false){
            message = "你不在该房间中";
            success = false;
            result = new Result<Boolean>().result(HttpStatus.OK,message,success);
            return new ResponseEntity<Result<Boolean>>( result,HttpStatus.OK);
        }

        matchService.prepare(id, roomId);
        return new ResponseEntity<Result<Boolean>>(result, HttpStatus.OK);
    }

    @ApiOperation(value = "好友房间取消准备",notes = "好友房间按下取消准备按钮之后发送的请求")
    @GetMapping("cancelPrepare")
    public ResponseEntity<Result<Boolean>> cancelPrepare(Long id, String roomId)
    {
        boolean success = true;
        String message = "你已取消准备";
        Result<Boolean> result = new Result<Boolean>().ok(message,success);
        if(matchService.isWaitingRoomExist(roomId) == false){
            message = "房间不存在";
            success = false;
            result = new Result<Boolean>().result(HttpStatus.OK, message,success);
            return new ResponseEntity<Result<Boolean>>( result,HttpStatus.OK);
        }
        if(matchService.isUserInWaitingRoom(id, roomId) == false){
            message = "你不在该房间中";
            success = false;
            result = new Result<Boolean>().result(HttpStatus.OK,message,success);
            return new ResponseEntity<Result<Boolean>>( result,HttpStatus.OK);
        }

        matchService.cancelPrepare(id, roomId);
        return new ResponseEntity<Result<Boolean>>(result, HttpStatus.OK);
    }

    @ApiOperation(value = "重连",notes = "重连回到游戏房间，返回重连相关信息")
    @GetMapping("reconnect")
    public ResponseEntity<Result<ReconnectVo>> reconnect(Long id)
    {
        String message = "重连成功";
        Result<ReconnectVo> result = new Result().ok(message,null);
        Long roomID = matchService.findRoomIDByUser(id);
        if(roomID == null){
            message = "游戏已结束";
            result = new Result().ok(message,null);
            return new ResponseEntity<Result<ReconnectVo>>( result,HttpStatus.OK);
        }else{
            ReconnectVo reconnectVo = matchService.reconnect(id, roomID);
            message = "重连成功";
            result = new Result().ok(message,reconnectVo);
            return new ResponseEntity<Result<ReconnectVo>>( result,HttpStatus.OK);
        }
        
    }
}
